package com.lineengine.lineengine.result;

import cn.hutool.core.collection.CollUtil;
import com.lineengine.lineengine.common.ErrorType;
import com.lineengine.lineengine.context.IContext;
import com.lineengine.lineengine.common.CommonErrorCode;
import com.lineengine.lineengine.utils.CommonUtil;

import java.util.List;


/**
 * <p>
 * 抽象并行业务执行结果
 * </p>
 *
 * @author wenrong.yu
 * @since 2020-11-08 18:05
 */
public class ParallelResult<T extends IContext<T>> extends DefaultResult<T> {
    private final List<IResult<T>> results;

    public ParallelResult(List<IResult<T>> results) {
        if (CollUtil.isEmpty(results)) {

        }
        this.results = results;
        this.analysisResults();
    }

    private void analysisResults() {
        // 成功
        List<IResult<T>> failResults = CommonUtil.filter(results, result -> !result.isSuccess());
        if (failResults.isEmpty()) {
            defaultSuccess();
            return;
        }
        // size = 1
        if (failResults.size() == 1) {
            failFromOne(failResults.get(0));
            return;
        }
        // size > 1
        failFromMany(failResults);
    }

    private void failFromMany(List<IResult<T>> failResults) {
        this.success = false;
        this.code = CommonErrorCode.INTERNAL_SERVER_ERROR.getCode();
        this.message = CollUtil.join(CommonUtil.collect(failResults, IResult::getMessage), ",");
        this.errorType = failResults.stream().anyMatch(result -> ErrorType.SERVER == result.getErrorType()) ? ErrorType.SERVER : ErrorType.CLIENT;
    }

    private void failFromOne(IResult<T> result) {
        this.success = false;
        this.errorType = result.getErrorType();
        this.code = result.getCode();
        this.message = result.getMessage();
    }

    private void defaultSuccess() {
        this.success = true;
        this.errorType = ErrorType.NONE;
        this.code = CommonErrorCode.SUCCESS.getCode();
        this.message = CommonErrorCode.SUCCESS.getMessage();
    }
}
